from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
from passlib.hash import pbkdf2_sha256

from tortoise.contrib.fastapi import register_tortoise

import jwt
from dotenv import dotenv_values

from models import *


app = FastAPI()
oauth2_sheme = OAuth2PasswordBearer(tokenUrl='/token')
secrets = dotenv_values('.env')


@app.post('/token')
async def generate_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user_obj = await User.get(username=form_data.username)
    if user_obj:
        if user_obj.verify_password(form_data.password):
            token_payload = {
                "id": user_obj.id,
                "username": user_obj.username
            }
            token = jwt.encode(token_payload, secrets['JWT_SECRET'], algorithm='HS256')
            return {'access_token': token, 'token_type': 'bearer'}
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail='invalid username or password',
        )
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail='not a valid username',
    )


@app.get('/')
async def test(token: str = Depends(oauth2_sheme)):
    # print('1'*111)
    # print(f'token: {token}')
    return {'token': token}


@app.post('/users')
async def create_user(user: userIn_pydantic):
    # new_user = await User.create(**user.dict(exclude_unset=True))
    # print('1'*111)
    # print(user)
    # print(user.password_hash)
    user.password_hash = pbkdf2_sha256.hash(user.password_hash)
    user_obj = await User.create(**user.dict(exclude_unset=True))
    # return await userOut_pydantic.from_queryset(User.all())
    # return await userOut_pydantic.from_tortoise_orm(User.all())
    return await userOut_pydantic.from_tortoise_orm(user_obj)

register_tortoise(
    app,
    db_url='sqlite://db.sqlite3',
    generate_schemas=True,
    add_exception_handlers=True,
    modules={'models': ['models']},
)
